package image;

import java.awt.Dimension;

import javax.media.opengl.GL2;

public class DrawUtil {
	/**
	 * Given a texture which contains a rectangle that has been deformed with perspective, this method
	 * can be used to perform the inverse transform and draw a flat rectangle back to the screen.
	 * 
	 * The texture coordinates are computed from the deformed points divided by the total texture size,
	 * and the perspective deformation is performed by computing the inverse w coordinate for the deformation. 
	 * 
	 * @see "Nathan Reed"
	 * 
	 * @param deformation The deformed 2D points of the source rectangle, in counter-clockwise order.
	 * The upper right corner is the first point.
	 * @param textureSize The width and height of the texture
	 * @param drawSize The width and height of the rectangle to draw 
	 */
	public static void renderUndeformed(GL2 gl, V3F[] deformation, Dimension textureSize, Dimension drawSize)
	{
		V3F[] df = deformation;
		Dimension ts = textureSize;
		//Perspective transform(using distances to the crossing of diagonals) method coutesy of Nathan Reed
		float cX,cY;
		{
			//Here, we calculate the crossing point(cX, cY) of the quad's diagonals.
			float x0=df[1].x(), y1=df[1].y();
			float x1=df[3].x(), y2=df[3].y();
			float x2=df[2].x(), y3=df[2].y();
			float x3=df[0].x(), y4=df[0].y();

			float div = ((x0-x1)*(y3-y4)-(y1-y2)*(x2-x3));
			if(div==0)
			{cX = (x0+x1+x2+x3)/4;
			cY = (y1+y2+y3+y4)/4;}
			else
			{cX = ((x0*y2-y1*x1)*(x2-x3)-(x0-x1)*(x2*y4-y3*x3))/div;
			cY = ((x0*y2-y1*x1)*(y3-y4)-(y1-y2)*(x2*y4-y3*x3))/div;}
		}
		//Here, we calculate the distances from the diagonal crossing to the points
		float d0 = (float) Calc.dist(cX, cY, df[0].x(), df[0].y());
		float d1 = (float) Calc.dist(cX, cY, df[1].x(), df[1].y());
		float d2 = (float) Calc.dist(cX, cY, df[2].x(), df[2].y());
		float d3 = (float) Calc.dist(cX, cY, df[3].x(), df[3].y());
		//Here, we calculate the q texture coordinate for all points.
		float p0 = 1f/((d0+d2)/d2);
		float p1 = 1f/((d1+d3)/d3);
		float p2 = 1f/((d2+d0)/d0);
		float p3 = 1f/((d3+d1)/d1);

		gl.glBegin(GL2.GL_TRIANGLE_STRIP);
		gl.glTexCoord4f(p1*df[1].x()/ts.width, p1*df[1].y()/ts.height, 0, p1);
		gl.glVertex2f(0,0);
		gl.glTexCoord4f(p2*df[2].x()/ts.width, p2*df[2].y()/ts.height, 0, p2);
		gl.glVertex2f(0,drawSize.height);
		gl.glTexCoord4f(p0*df[0].x()/ts.width, p0*df[0].y()/ts.height, 0, p0);
		gl.glVertex2f(drawSize.width,0);
		gl.glTexCoord4f(p3*df[3].x()/ts.width, p3*df[3].y()/ts.height, 0, p3);
		gl.glVertex2f(drawSize.width,drawSize.height);
		gl.glEnd();
	}

}
